﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceProcess;
using Microsoft.Win32;
using PCDoctor.Utils;

namespace PCDoctor.ScanParameters
{
    public class ServicesScanParameter : ScanParameter
    {
        public ServicesScanParameter(string name, string path, string value, Int64 problemId) :
            base(name, path, value, problemId)
        {
            Kind = ScanFixerKinds.Services;
        }

        public override void RestoreDefault()
        {
            RegistryKey hauberk = Registry.LocalMachine.OpenSubKey("Software\\Hauberk Software\\");
            //Если ключа нет, то можно дальше ничего и не делать
            if (hauberk == null)
            {
                return;
            }
            RegistryKey backupKey = Registry.LocalMachine.OpenSubKey("Software\\Hauberk Software\\PCDoctorBackup\\");
            if (backupKey == null)
            {
                return;
            }
            //Теперь собстно восстанавливаем
            foreach (KeyValuePair<string, string> kv in PathsValues)
            {
                RegistryKey problemKey = backupKey.OpenSubKey("problem_" + ProblemId.ToString() +
                "__param_" + kv.Key);
                if (problemKey == null)
                {
                    continue;
                }
                object path = problemKey.GetValue("Path");
                object value = problemKey.GetValue("Value");
                string[] valueParts = value.ToString().Split('+');
                try
                {
                    ServiceController sc = new ServiceController(path.ToString());
                    if (valueParts[valueParts.Length - 1] == "running")
                    {
                        sc.Start();
                    }
                    if (!(this is GameModeParameter))
                    {
                        setServiceStatus(path.ToString(), long.Parse(valueParts[0]));
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        public override FixationResult Fix()
        {
            if (this.Result == ScanResult.OK)
            {
                FixResult = FixationResult.NoNeedToFix;
                return FixationResult.NoNeedToFix;
            }
            FixedProblems = 0;
            FixResult = FixationResult.DontBegin;
            foreach (KeyValuePair<string, string> kv in PathsValues)
            {
                try
                {
                    ServiceController sc = new ServiceController(kv.Key);
                    if (sc.CanStop && sc.Status == ServiceControllerStatus.Running)
                    {
                        FixedProblems++;
                        sc.Stop();
                        setServiceStatus(kv.Key, 4);
                    }
                }
                catch (Exception)
                {
                    FixedProblems--;
                    FixResult = FixationResult.Error;
                }
            }
            if (FixResult == FixationResult.DontBegin)
            {
                FixResult = FixationResult.Fixed;
            }
            return FixResult;
        }

        protected string getServiceStatus(string servName)
        {
            string result = "3";
            try
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(
                    @"SYSTEM\CurrentControlSet\Services\" + servName);
                result = key.GetValue("Start").ToString();
            }
            catch (Exception)
            {
                result = "4";
            }
            return result;
        }

        protected bool setServiceStatus(string servName, long status)
        {
            bool result = true;
            try
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(
                    @"SYSTEM\CurrentControlSet\Services\" + servName, true);
                key.SetValue("Start", status, RegistryValueKind.DWord);
            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e.Message);
                result = false;
            }
            return result;
        }

        public override bool Scan()
        {
            ProblemsCount = 0;
            foreach (KeyValuePair<string, string> kv in PathsValues)
            {
                try
                {
                    ServiceController sc = new ServiceController(kv.Key);
                    if (sc.CanStop && sc.Status == ServiceControllerStatus.Running)
                    {
                        string status = "running";
                        if (sc.Status != ServiceControllerStatus.Running &&
                            sc.Status != ServiceControllerStatus.PausePending &&
                            sc.Status != ServiceControllerStatus.Paused &&
                            sc.Status != ServiceControllerStatus.StartPending)
                        {
                            status = "stopped";
                        }
                        DoBackup(kv.Key, getServiceStatus(kv.Key) + "+" + status, kv.Key);
                        Result = ScanResult.Problem;
                        ProblemsCount++;
                    }
                }
                catch (Exception e)
                {
                    ErrorHandler.HandleError(e.Message);
                    //Result = ScanResult.NotFound;
                }
            }
            if (Result == ScanResult.NotScanned)
            {
                Result = ScanResult.OK;
            }
            return true;
        }
    }
}
